%{

#include <verilog.h>

#define YYDEBUG 1
#define YYERROR_VERBOSE 1

using namespace std;

// stuff from flex that bison needs to know about:
extern "C" int verilog_lex();
extern "C" int verilog_parse();
extern "C" FILE *verilog_in;
extern int verilog_line_number; 
void verilog_error(const char *s);

%}

%union {
  float fval;
  char cval;
  char *sval;
}

%error-verbose

%token <cval> CHAR
%token <fval> NUMBER
%token <sval> STRING
%token MODULE

%%

/***************************************************************
                           SOURCE_TEXT
****************************************************************/

source_text:
    description
    ;

description:
    module_declaration
    ;

module_declaration:
    MODULE module_identifier list_of_ports ';'
        module_items
    ENDMODULE
    ;

list_of_ports:
    '(' port ports ')'
    ;

ports:
    ports ',' port
    | ',' port
    ;

port:
    | port_expression
    ;

port_expression:
    port_idenitifier
    | port_identifier '[' constant_range_expression ']'
    ;

module_items:
    | module_items module_item
    | module_item
    ;

module_item:
    port_declaration ';'
    | non_port_module_item
    ;

non_port_module_item:
    module_or_generate_item
    ;

module_or_generate_item:
    module_or_generate_item_declaration
    | module_instantiation
    ;

module_or_generate_item_declaration:
    net_declaration
    ;

//TODO
module_instantiation:
    ;

/***************************************************************
                           DECLARATIONS
****************************************************************/

// TODO
port_declaration:
    ;

//TODO
net_declaration:
    ; 


%%

int readVerilog(Library* library,string filename) {

  cout << "INFO: Reading LEF file " << filename << endl;

  verilog::library = library;
  verilog::technology = library->getTechnology();

  // open a file handle to a particular file:
  verilog_in = fopen(filename.c_str(), "r");

  // make sure it is valid:
  if (!verilog_in) {
    cout << "Failed to open LEF file " << filename << " for read!" << endl;
    return 1;
  }
        
  // parse through the input until there is no more:
  do {
    if( verilog_parse() ) {
      fclose(verilog_in);
      return 1;
    }
  } while (!feof(verilog_in));

  cout << "INFO: Finished reading LEF file " << filename << endl;

  return 0;
 
}

void verilog_error(const char *msg) {

  cout << "DEF parse error on line " << verilog_line_number <<". Message :" << msg << endl;

}
